﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.ComponentModel;
using System.Windows;
using System.Threading;
using System.IO;
using System.Windows.Threading;

namespace ThreadingSample
{
    public class CardThread : Card
    {
        //--------------------------------------------------------------------------------------------------------------------------

        private static Thread m_ImageLoaderThread;

        private static AutoResetEvent m_LoadImageEvent = new AutoResetEvent(false);

        private static readonly Queue<CardThread> m_LockImageLoad = new Queue<CardThread>();

        //--------------------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 
        /// </summary>
        static CardThread()
        {
            m_ImageLoaderThread = new Thread(new ThreadStart(ImageLoaderThreadLoop));
            m_ImageLoaderThread.IsBackground = true;  // otherwise, the app won't quit with the UI...
            m_ImageLoaderThread.Priority = ThreadPriority.BelowNormal;
            m_ImageLoaderThread.Start();
        }

        //--------------------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 
        /// </summary>
        private static void ImageLoaderThreadLoop()
        {
           do
            {
                m_LoadImageEvent.WaitOne();

                try
                {
                    while (ImageLoaderStack(null))
                    {
                        Thread.Sleep(1);
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex);
                }
            } while (true);
        }

        //--------------------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 
        /// </summary>
        private static bool ImageLoaderStack(object o)
        {
            CardThread p = null;
            lock (m_LockImageLoad)
            {
                if (m_LockImageLoad.Count > 0)
                {
                    p = m_LockImageLoad.Dequeue();
                }
            }

            if (p != null)
            {
                p.DoLoadImage();
                return true;
            }

            return false;
        }

        //--------------------------------------------------------------------------------------------------------------------------

        /// <summary>
        /// 
        /// </summary>
        private static void AddImageToLoad(CardThread p)
        {
            lock (m_LockImageLoad)
            {
                m_LockImageLoad.Enqueue(p);
            }
            // signal we've got something
            m_LoadImageEvent.Set();
        }

        ////--------------------------------------------------------------------------------------------------------------------------

        public CardThread(string filename)
            :base(filename)
        {
        }

        //--------------------------------------------------------------------------------------------------------------------------

        //protected override void LoadImage()
        //{
        //}

        //--------------------------------------------------------------------------------------------------------------------------

        public override void LoadImage()
        {
            AddImageToLoad(this);
        }

        //--------------------------------------------------------------------------------------------------------------------------
    }
}